<template>
  <!-- 多个文件上传 -->
  <el-upload
    class="w-100%"
    v-model:file-list="fileList"
    multiple
    drag
    v-loading="uploading"
    :http-request="handleOssUpload"
    :on-remove="handleRemoveFile"
    :on-preview="handlePreview"
    :limit="limit"
  >
    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
    <div class="el-upload__text"> 拖拽到此处或<em>点击上传</em> </div>
    <template #tip>
      <div class="el-upload__tip"> 最多上传{{ limit }}个文件，文件大小不超过1024MB </div>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import type { UploadFile, UploadRequestOptions } from 'element-plus'
import { getOssDirectUploadParams, batchSaveDirectUploadInfo } from '@/api/upload'
import { createOssFilePath, createFileName } from '@/utils'
const props = defineProps({
  directory: {
    type: Number,
    default: 2
  },
  limit: {
    type: Number,
    default: 1
  },
  fileListMap: {
    type: Array,
    default: () => []
  }
})
const emits = defineEmits(['uploadSuccessRes', 'handleRemoveFile', 'uploadError'])

const uploading = ref(false)
const fileList = ref<any[]>([])
// 自定义上传到阿里云 OSS
const handleOssUpload = async (options: UploadRequestOptions) => {
  uploading.value = true
  const { file } = options
  try {
    console.log('fileList', fileList.value, file)
    if (fileList.value.length >= props.limit) {
      ElMessage.error({
        message: `上传文件数量不能超过 ${props.limit} 个!`
      })
      return
    }
    // 获取文件扩展名
    const fileExtension = file.name.split('.').pop() ?? ''

    // 1. 从后端获取直传参数
    const ossParams = ossResponse.value
    const fileName = createFileName(fileExtension)
    console.log('fileName', fileName)
    const ossFilePath = createOssFilePath(fileName, ossParams.directory)
    console.log('ossFilePath', ossFilePath)
    // 前端文件大小校验
    if (file.size > ossParams.max_file_size) {
      const err_msg = `文件大小不能超过 ${ossParams.max_file_size / 1024 / 1024} MB`
      ElMessage.error(err_msg)
      const err = new Error(err_msg) as any
      err.status = 400
      err.method = 'POST'
      err.url = ossParams.host
      options.onError(err)
      return
    }

    // 2. 构造 FormData 并上传到阿里云
    const formData = new FormData()
    formData.append('key', ossFilePath)
    formData.append('policy', ossParams.policy)
    formData.append('OSSAccessKeyId', import.meta.env.VITE_ALIYUN_OSS_ACCESS_KEY_ID as string)
    formData.append('success_action_status', '200')
    formData.append('signature', ossParams.signature)
    formData.append('file', file)

    let response: Response | undefined
    try {
      response = await fetch(ossParams.host, {
        method: 'POST',
        body: formData
      })
    } catch (err) {
      console.log('err', err)
      response = undefined
    }
    if (!response || !response.ok) {
      const errorText = response ? await response.text() : '网络异常或无响应'
      console.error('OSS 上传失败，状态码:', response ? response.status : '无响应')
      console.error('OSS 错误内容:', errorText)
      ElMessage.error('OSS上传失败，详细错误见控制台')
      throw new Error('OSS上传失败: ' + errorText)
    }

    // 上传成功, 构造可预览的 URL
    const fileUrl = `${ossParams.host}/${ossFilePath}`
    fileList.value.forEach((item) => {
      if (item.uid === file.uid) {
        item.ossFilePath = ossFilePath
        item.url = fileUrl
      }
    })
  } catch (error) {
    console.error('上传失败:', error)
    ElMessage.error('上传失败，请检查控制台日志。')
    // 手动触发上传失败的回调
    options.onError(error as any)
    // 如果需要，可以从文件列表中移除失败的文件
  } finally {
    uploading.value = false
  }
}

const handleRemoveFile = (file: UploadFile) => {
  console.log('fileList', fileList.value, file)
  // emits('handleRemoveFile', file)
}

// 点击文件列表中已上传的文件时的钩子
const handlePreview = (file: UploadFile) => {
  console.log('file', file)
  const previewUrl = file.url || (file.raw as any)?.url
  if (previewUrl) {
    window.open(previewUrl, '_blank')
  }
}
const ossResponse = ref<any>({})
const uploadImg = async () => {
  if (uploading.value) {
    return true
  }
  let images = fileList.value
    .filter((item) => item.ossFilePath)
    .map((item) => {
      return {
        name: item.name,
        directory: props.directory,
        url: item.ossFilePath
      }
    })
  console.log('images', images)
  if (images.length === 0) {
    return false
  }
  const saveRes: any = await batchSaveDirectUploadInfo({ images })
  if (saveRes.code !== 0) {
    ElMessage.error('保存文件信息失败: ' + (saveRes.message || '未知错误'))
    throw new Error('保存文件信息失败')
  }
  emits('uploadSuccessRes', saveRes.data)
}
onMounted(async () => {
  console.log('fileList', fileList.value) // 1. 从后端获取直传参数
  const paramsRes: any = await getOssDirectUploadParams({ directory: props.directory }) // 目录7代表固件
  if (paramsRes.code !== 0) {
    ElMessage.error('获取上传参数失败: ' + (paramsRes.message || '未知错误'))
    throw new Error('获取上传参数失败')
  }
  ossResponse.value = paramsRes.data
})
watch(
  props.fileListMap,
  () => {
    console.log('props.fileListMap', props.fileListMap)
    fileList.value = props.fileListMap
  },
  { immediate: true }
)
defineExpose({
  uploadImg
})
</script>

<style lang="less" scoped></style>
